#include <iostream>
#include "rrrenderer.h"
#include <cstdio>
#include <SDL_image.h>
#include <SDL_endian.h>
#include "rrmath.h"

RRRenderer rend;
RRVertexArray varray;

SDL_Surface *screen = NULL;
SDL_Surface *backscreen = NULL;
SDL_Surface *background_image = NULL;

void Update(void)
{
    /* here to code processes to update the state */
}

void DrawPixel(SDL_Surface *screen)
{
    //Uint32 color = SDL_MapRGB(screen->format, R, G, B);

    if(SDL_MUSTLOCK(screen)) {
        if(SDL_LockSurface(screen) < 0) {
            return;
        }
    }

    int x, y;

    for(x=0; x<640; x++)
        for(y=0; y<480; y++) {
            Uint32 *bufp;
            bufp = (Uint32 *)screen->pixels + y*screen->pitch/4 + x;
            *bufp = 0;
        }

    static float deg = 0.0;
    //    rend.rrDraw(&prim, screen);
    //    rend.rrDraw(&prim2, screen);
    //    rend.rrDraw(&prim3, screen);
    //    rend.rrDraw(&prim4, screen);
    rend.rrFlash();
    rend.rrRotateY(deg);
    rend.rrDraw(&varray, screen);
    deg += 1.0;

    if(SDL_MUSTLOCK(screen)) {
        SDL_UnlockSurface(screen);
    }
    // SDL_UpdateRect(screen, x, y, 1, 1);
}

void Draw(void)
{
    /* SDL_BlitSurface(background_image, NULL, screen, NULL); */

    /* here to code drawing processes  */
    DrawPixel(backscreen);

    // update screen
    SDL_BlitSurface(backscreen, NULL, screen, NULL);
    SDL_Flip(screen);

    //puts("Im in Draw");
    // SDL_UpdateRect(backscreen, 0, 0, 0, 0);
}

int Initialize(void)
{
    if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER) < 0) {
        fprintf(stderr, "failed to initialize SDL: %s\n", SDL_GetError());
        return -1;
    }

    SDL_WM_SetCaption("My SDL Sample", NULL);

    screen = SDL_SetVideoMode(640, 480, 32, SDL_SWSURFACE | SDL_DOUBLEBUF);

    backscreen = SDL_SetVideoMode(640, 480, 32, SDL_SWSURFACE);

    if(screen == NULL) {
        fprintf(stderr, "failed to initialize the screen: %s\n", SDL_GetError());
        SDL_Quit();
        return -1;
    }

    RRVertex vert;
    vert.w = 1.0f;
    vert.c[0] = 1.0f; vert.c[1] = 0.0f;
    vert.c[2] = 0.0f; vert.c[3] = 1.0f;

    int stacks, slices;
    stacks = 32; slices = 32;
    /* 頂点の位置 */
    for (int j = 0; j <= stacks; ++j) {
        float ph = 3.141593f * (float)j / (float)stacks;
        float y = cosf(ph);
        float r = sinf(ph);

        for (int i = 0; i <= slices; ++i) {
            float th = 2.0f * 3.141593f * (float)i / (float)slices;
            float x = r * cosf(th);
            float z = r * sinf(th);

            float len = sqrtf(x * x + y * y + z * z);
            vert.nx = x / len;
            vert.ny = y / len;
            vert.nz = z / len;

            vert.x = x;
            vert.y = y;
            vert.z = z;
            varray.rrAddVertex(&vert);
        }
    }

    /* 面の指標 */
    for (int j = 0; j < stacks; ++j) {
        for (int i = 0; i < slices; ++i) {
            int count = (slices + 1) * j + i;
            /* 上半分 */
            varray.rrAddFace(count, count + 1, count + slices + 2);
            /* 下半分 */
            varray.rrAddFace(count, count + slices + 2, count + slices + 1);
        }
    }

    return 0;
}

void MainLoop(void)
{
    SDL_Event event;
    double next_frame = SDL_GetTicks();
    double current_time;
    double elapsed_time = 0.0;
    double prev_time = 0.0;
    double wait = 1000.0 / 60;
    int frame_cnt = 0;
    double fps = 0.0;

    while(1) {
        //puts("Im in MainLoop");
        /* deal with all events */
        while(SDL_PollEvent(&event)) {
            if((event.type == SDL_QUIT) || (event.type == SDL_KEYUP && event.key.keysym.sym == SDLK_ESCAPE)) {
                //puts("Im dealing with SDL_QUIT");
                return;
            }
        }
//        if(SDL_GetTicks() >= next_frame) {
//            //puts("Im dealing with Update");
           Update();
//            if(SDL_GetTicks() < next_frame + wait) {
//                //puts("im dealing with Draw");
                Draw();
//            }
//            next_frame += wait;
            SDL_Delay(0);
//        }
        frame_cnt++;
        if(frame_cnt >= 5) {
            current_time = SDL_GetTicks();
            elapsed_time = current_time - prev_time;
            fps = 1000.0 * 5.0 / elapsed_time;
            frame_cnt = 0;
            prev_time = current_time;
            printf("%f\n", fps);
        }
    }
}

void Finalize(void)
{
    /* here to free images and sounds */
    // SDL_FreeSurface(background_image);

    SDL_Quit();
}

int main(int argc, char *argv[])
{
    if(Initialize() < 0)
        return -1;

    // printf("%d\n", screen->pitch);

    MainLoop();

    Finalize();

    return 0;
}

